import os
from langchain_openai import ChatOpenAI
"""函数值无法传入到提示词里面去"""

from langchain_core.prompts import PromptTemplate
# 导入 代理创建函数 和 代理执行器
from langchain.agents import create_react_agent, AgentExecutor
from langchain.memory import ConversationBufferMemory

from .tools import tools
from db.db_work import get_db_info


# OpenAI配置
# OPENAI_API_KEY = 'sk-W3u9YKJyZf1yS4G6Lv1ynfe299eoB0u2RDg9FOJC3hkvxf9e'
# BASE_URL = "https://api.chatanywhere.tech"
# MODEL = "gpt-4o"


OPENAI_API_KEY = 'sk-kmqzsejzspyeuhzgrrajsxuzjtlpdlmhorymtfickhniittw'
BASE_URL = "https://api.siliconflow.cn/v1"
MODEL = "Qwen/QwQ-32B"

"""模型配置"""
chat_model = ChatOpenAI(
    openai_api_key=OPENAI_API_KEY,
    base_url=BASE_URL,
    model=MODEL,
)





"""提示词配置"""
template = """请尽可能好地回答以下问题。如果需要，可以适当的使用一些功能。

# 注意事项
1、一定要用中文回答用户问题
2、如果需要用到数据库，请认真阅读数据库信息

# 数据库信息 
1、数据库采用sqllite数据库
2、数据库中所有的表，以及表对应的列信息如下：{dbinfo}

你有以下工具可用：\n
{tools}\n
{chat_history}\n
请严格按照以下格式输出，任何情况下都不能省略或修改格式（即使遇到错误）：\n
Question: 需要回答的问题。\n
Thought: 总是考虑应该做什么以及使用哪些工具。\n
Action: 应采取的行动，应为 [{tool_names}] 中的一个。\n
Action Input: 行动的输入。\n
Observation: 行动的结果。\n
... (这个 Thought/Action/Action Input/Observation 过程可以重复零次或者多次)。\n
Thought: 我现在知道最终答案了。\n
Final Answer: 对原问题的最终答案。\n
开始！ \n
Quesion: {input}\n
Thought: {agent_scratchpad}\n
"""

dbinfo = str(get_db_info())
dbinfo = dbinfo.replace('{','(')
dbinfo = dbinfo.replace('}',')')

template = template.replace("{dbinfo}", dbinfo)
# print(template)
prompt = PromptTemplate.from_template(template)



"""创建react 方式的智能体"""
agent = create_react_agent(chat_model, tools, prompt, stop_sequence=["\nObserv"])

'''记忆组件--------------------------------------'''
# 按照新的推荐方式初始化
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True  # 添加此参数以兼容未来版本
)

"""创建代理执行器"""
agent_executor = AgentExecutor.from_agent_and_tools(
    agent=agent,
    tools=tools,
    memory=memory,
    verbose=True,
    handle_parsing_errors=True
)



# 运行代理的函数
async def run_agent(query):
    response = await agent_executor.ainvoke({"input": query})
    return response["output"]